package cn.com.utils;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        context = applicationContext;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        setApplicationContext(event.getApplicationContext());
    }

    /**
     * 获取ApplicationContext
     *
     * @return {@link ApplicationContext }
     */
    public static ApplicationContext getApplicationContext() {
        return context;
    }

    /**
     * 获取bean
     *
     * @param beanClass bean类
     * @param <T>       bean类型
     * @return {@link T }
     */
    public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    /**
     * 获取bean
     *
     * @param beanName  bean名称
     * @param beanClass bean类
     * @param <T>       bean类型
     * @return {@link T }
     */
    public static <T> T getBean(String beanName, Class<T> beanClass) {
        return context.getBean(beanName, beanClass);
    }

    /**
     * 获取bean
     *
     * @param beanName bean名称
     * @return {@link Object }
     */
    public static Object getBean(String beanName) {
        return context.getBean(beanName);
    }

    /**
     * 检查是否包含bean
     *
     * @param beanName bean名称
     * @return boolean 是否包含
     */
    public static boolean containsBean(String beanName) {
        return context.containsBean(beanName);
    }

    /**
     * 检查bean是否为单例
     *
     * @param beanName bean名称
     * @return boolean 是否为单例
     */
    public static boolean isSingleton(String beanName) {
        return context.isSingleton(beanName);
    }

    /**
     * 获取bean的类型
     *
     * @param beanName bean名称
     * @return {@link Class }<{@link ?}>
     */
    public static Class<?> getType(String beanName) {
        return context.getType(beanName);
    }

    /**
     * 获取指定类型的所有bean名称
     *
     * @param beanClass bean类
     * @param <T>       bean类型
     * @return {@link String[] } bean名称数组
     */
    public static <T> String[] getBeanNamesForType(Class<T> beanClass) {
        return context.getBeanNamesForType(beanClass);
    }
}
